package bai.tool.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;

/**
 * 全局静态计时器
 */
public class CodeTimer {

    final static Logger log = LoggerFactory.getLogger(CodeTimer.class);
    // 配置常量
    private static final boolean DEFAULT_SILENT = false;
    private static final boolean NANO_MODE = true;

    // 全局单例（用于非线程隔离模式）
    private static volatile CodeTimer instance;

    // 线程隔离存储
    private static final ThreadLocal<CodeTimer> threadLocalTimer = ThreadLocal.withInitial(() -> {
        CodeTimer timer = new CodeTimer();
        start(); // 每个线程首次使用自动初始化
        return timer;
    });

    // 状态存储
    private final AtomicLong startHolder = new AtomicLong(0);
    private final AtomicLong lastInterval = new AtomicLong(0);
    private final AtomicInteger counter = new AtomicInteger(0);

    // 配置参数
//    private static Consumer<String> globalLogConsumer = System.out::printf;
    private static Consumer<String> globalLogConsumer = log::info;
    private static boolean globalSilent = DEFAULT_SILENT;

    /**
     * 静态方法区域
     */
    public static void start() {
        currentTimer().doStart();
    }

    public static void mark() {
        mark(null);
    }

    public static void mark(String tag) {
        currentTimer().doMark(tag);
    }

    public static void config(Consumer<String> logConsumer, boolean silent) {
        globalLogConsumer = logConsumer;
        globalSilent = silent;
    }

    /**
     * 私有实例方法
     */
    private void doStart() {
        startHolder.set(currentTime());
        lastInterval.set(0);
        counter.set(0);
    }

    private void doMark(String tag) {
        long now = currentTime();
        long start = startHolder.get();

        long totalElapsed = now - start;
        long prev = lastInterval.getAndSet(totalElapsed);
        long delta = totalElapsed - prev;

        int currentCount = counter.incrementAndGet();

        if (!globalSilent) {
            String message = formatMessage(tag, currentCount, delta, totalElapsed);
            globalLogConsumer.accept(message);
        }
    }

    /**
     * 获取当前线程的计时器实例
     */
    private static CodeTimer currentTimer() {
        // 根据需求选择模式
        if (isThreadSafeMode()) {
            return threadLocalTimer.get();
        } else {
            if (instance == null) {
                synchronized (CodeTimer.class) {
                    if (instance == null) {
                        instance = new CodeTimer();
                        instance.doStart();
                    }
                }
            }
            return instance;
        }
    }

    /**
     * 时间计算相关方法
     */
    private static long currentTime() {
        return NANO_MODE ? System.nanoTime() : System.currentTimeMillis();
    }

    private String formatMessage(String tag, int count, long delta, long total) {
        if (NANO_MODE) {
            return (tag != null) ?
                    String.format("[%s] 第%d次间隔 %.3fms 总计 %.3fms%n" ,
                            tag, count, delta / 1e6, total / 1e6) :
                    String.format("第%d次间隔 %.3fms 总计 %.3fms%n" ,
                            count, delta / 1e6, total / 1e6);
        } else {
            return (tag != null) ?
                    String.format("[%s] 第%d次间隔 %dms 总计 %dms%n" , tag, count, delta, total) :
                    String.format("第%d次间隔 %dms 总计 %dms%n" , count, delta, total);
        }
    }

    /**
     * 模式开关（根据需求设置）
     */
    private static boolean isThreadSafeMode() {
        return false; // 默认开启线程隔离模式
    }
}

